using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using Andrewl.XnaHelpers.Audio;
using Andrewl.XnaHelpers.Input;
using Andrewl.XnaHelpers.Storage;
using Andrewl.XnaHelpers.Guide_Helper;

namespace Andrewl.XnaHelpers
{
    public class FrameRateCounter : DrawableGameComponent
    {
        private SpriteFont font;
        private SpriteBatch batch;

        private Vector2 position;
        private Color color;

        private int frameRate = 0;
        private int frameCounter = 0;
        TimeSpan elapsedTime = TimeSpan.Zero;

        private int lowestFramerate = 0;
        private int highestFramerate = 0;
     
        private bool firstRun;
        private string fps;

        private bool UseSafeArea = false;

        private ResourceContentManager _eContent;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="game">Just pass "this" with no quotes</param>
        /// <param name="updateTime">How often to redisplay the framerate in seconds</param>
        /// <param name="position">Where to display it</param>
        /// <param name="color">Color to draw it as along with the transparency</param>
        public FrameRateCounter(Game game, Vector2 Position, Color Color)
            : base(game)
        {
            this.position = Position;
            this.color = Color;
            UseSafeArea = false;
        }

        public FrameRateCounter(Game game, Color Color) : base(game)
        {
            this.color = Color;
            UseSafeArea = true;
        }

        public override void Initialize()
        {
            base.Initialize();
            if (UseSafeArea)
                this.position = new Vector2(GraphicsDevice.DisplayMode.TitleSafeArea.Location.X, GraphicsDevice.DisplayMode.TitleSafeArea.Location.Y);
            this.firstRun = true;
            UpdateOrder = 100; //so that our FPS always shows up by making it be drawn last or most likely last since I doubt anyone will have 100 game components running
        }

        protected override void LoadContent()
        {
            _eContent = new ResourceContentManager(Game.Services, embed.ResourceManager);
            batch = new SpriteBatch(GraphicsDevice);
#if WINDOWS
            font = _eContent.Load<SpriteFont>("DebugFont_x86");
#endif
#if XBOX
            font = _eContent.Load<SpriteFont>("DebugFont_xbox");
#endif
            base.LoadContent();
        }

        public override void Update(GameTime gameTime)
        {
            elapsedTime += gameTime.ElapsedGameTime;

            if (elapsedTime > TimeSpan.FromSeconds(1))
            {
                elapsedTime -= TimeSpan.FromSeconds(1);
                frameRate = frameCounter;
                frameCounter = 0;

                #region Statistics

                if (firstRun)
                {
                    lowestFramerate = frameRate;
                    highestFramerate = frameRate;
                    firstRun = false;
                }
                else
                {
                    if (frameRate < lowestFramerate)
                    {
                        lowestFramerate = frameRate;
                    }

                    if (frameRate > highestFramerate)
                    {
                        highestFramerate = frameRate;
                    }
                }

                #endregion
            }

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            frameCounter++;

            this.fps = string.Empty;
            this.fps = string.Format("FixedTimestep:{0} \n FPS:{1} \n H:{2} \n L:{3}", new string[] { Game.IsFixedTimeStep.ToString(), frameRate.ToString(), highestFramerate.ToString(), lowestFramerate.ToString() });

            batch.Begin();
            batch.DrawString(font, fps, position, color);
            batch.End();

            base.Draw(gameTime);
        }

    }

}